In [ ]:
#util and imports
import os
import fnmatch
from cStringIO import StringIO
import numpy as np
import PIL.Image
import IPython.display
import shutil
def list_all_files(directory, extensions=None):
for root, dirnames, filenames in os.walk(directory):
for filename in filenames:
base, ext = os.path.splitext(filename)
joined = os.path.join(root, filename)
if extensions is None or ext.lower() in extensions:
yield joined
def show_array(a, fmt='png', filename=None):
a = np.uint8(np.clip(a, 0, 255))
image_data = StringIO()
PIL.Image.fromarray(a).save(image_data, fmt)
if filename is None:
IPython.display.display(IPython.display.Image(data=image_data.getvalue()))
else:
with open(filename, 'w') as f:
image_data.seek(0)
shutil.copyfileobj(image_data, f)
def find_rectangle(n, max_ratio=2):
sides = []
square = int(math.sqrt(n))
for w in range(square, max_ratio * square):
h = n / w
used = w * h
leftover = n - used
sides.append((leftover, (w, h)))
return sorted(sides)[0][1]
# should work for 1d and 2d images, assumes images are square but can be overriden
def make_mosaic(images, n=None, nx=None, ny=None, w=None, h=None):
if n is None and nx is None and ny is None:
nx, ny = find_rectangle(len(images))
else:
nx = n if nx is None else nx
ny = n if ny is None else ny
images = np.array(images)
if images.ndim == 2:
side = int(np.sqrt(len(images[0])))
h = side if h is None else h
w = side if w is None else w
images = images.reshape(-1, h, w)
else:
h = images.shape[1]
w = images.shape[2]
image_gen = iter(images)
mosaic = np.empty((h*ny, w*nx))
for i in range(ny):
ia = (i)*h
ib = (i+1)*h
for j in range(nx):
ja = j*w
jb = (j+1)*w
mosaic[ia:ib, ja:jb] = next(image_gen)
return mosaic
In [ ]:
negative_paths = list(list_all_files('SMILEsmileD-master/SMILEs/negatives/negatives7/', ['.jpg']))
print 'loaded', len(negative_paths), 'negative examples'
positive_paths = list(list_all_files('SMILEsmileD-master/SMILEs/positives/positives7/', ['.jpg']))
print 'loaded', len(positive_paths), 'positive examples'
examples = [(path, 0) for path in negative_paths] + [(path, 1) for path in positive_paths]
In [ ]:
import numpy as np
from skimage.measure import block_reduce
from skimage.io import imread
def examples_to_dataset(examples, block_size=2):
X = []
y = []
for path, label in examples:
img = imread(path, as_grey=True)
img = block_reduce(img, block_size=(block_size, block_size), func=np.mean)
img = img.reshape((32*32))
X.append(img)
if(label==0):
y.append((1,0))
else:
y.append((0,1))
return np.asarray(X), np.asarray(y)
%time X, Y = examples_to_dataset(examples)
X = np.asarray(X,dtype=np.float32)/ 255.
Y = np.asarray(Y,dtype=np.int32)
In [ ]:
# Split data into train and test set
from sklearn.cross_validation import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=0.1, random_state=2)
In [ ]:
#show Negative images
show_array(255 * make_mosaic(X[:len(negative_paths)], 8), fmt='jpeg') # negative at the beginning
In [ ]:
#show Positive images
show_array(255 * make_mosaic(X[-len(positive_paths):], 8), fmt='jpeg') # positive at the end
In [ ]:
import tensorflow as tf
In [ ]:
# Network Parameters
n_input = X.shape[1]
n_classes = 2 # (Smile vs. No Smile)
dropout = 0.75 # Dropout, probability to keep units
In [ ]:
# Parameters
learning_rate = 0.001
training_samples = X.shape[0]
batch_size = 128
display_step = 10
training_epochs=50
In [ ]:
# tf Graph input
x = tf.placeholder(tf.float32, [None, n_input])
y = tf.placeholder(tf.float32, [None, n_classes])
keep_prob = tf.placeholder(tf.float32) #dropout (keep probability)
In [ ]:
# Create AlexNet model
def conv2d(name, l_input, w, b):
return tf.nn.relu(tf.nn.bias_add(tf.nn.conv2d(l_input, w, strides=[1, 1, 1, 1],
padding='SAME'),b), name=name)
def max_pool(name, l_input, k):
return tf.nn.max_pool(l_input, ksize=[1, k, k, 1], strides=[1, k, k, 1],
padding='SAME', name=name)
def norm(name, l_input, lsize=4):
return tf.nn.lrn(l_input, lsize, bias=1.0, alpha=0.001 / 9.0, beta=0.75, name=name)
def alex_net(_X, _weights, _biases, _dropout):
# Reshape input picture
_X = tf.reshape(_X, shape=[-1, 32, 32, 1])
# Convolution Layer
conv1 = conv2d('conv1', _X, _weights['wc1'], _biases['bc1'])
# Max Pooling (down-sampling)
pool1 = max_pool('pool1', conv1, k=2)
# Apply Normalization
norm1 = norm('norm1', pool1, lsize=4)
# Apply Dropout
norm1 = tf.nn.dropout(norm1, _dropout)
# Convolution Layer
conv2 = conv2d('conv2', norm1, _weights['wc2'], _biases['bc2'])
# Max Pooling (down-sampling)
pool2 = max_pool('pool2', conv2, k=2)
# Apply Normalization
norm2 = norm('norm2', pool2, lsize=4)
# Apply Dropout
norm2 = tf.nn.dropout(norm2, _dropout)
# Convolution Layer
conv3 = conv2d('conv3', norm2, _weights['wc3'], _biases['bc3'])
# Max Pooling (down-sampling)
pool3 = max_pool('pool3', conv3, k=2)
# Apply Normalization
norm3 = norm('norm3', pool3, lsize=4)
# Apply Dropout
norm3 = tf.nn.dropout(norm3, _dropout)
# Fully connected layer
# Reshape conv3 output to fit dense layer input
dense1 = tf.reshape(norm3, [-1, _weights['wd1'].get_shape().as_list()[0]])
# Relu activation
dense1 = tf.nn.relu(tf.matmul(dense1, _weights['wd1']) + _biases['bd1'], name='fc1')
# Relu activation
dense2 = tf.nn.relu(tf.matmul(dense1, _weights['wd2']) + _biases['bd2'], name='fc2')
# Output, class prediction
out = tf.matmul(dense2, _weights['out']) + _biases['out']
return out
In [ ]:
# Store layers weight & bias
weights = {
'wc1': tf.Variable(tf.random_normal([3, 3, 1, 64],stddev=0.01)),
'wc2': tf.Variable(tf.random_normal([3, 3, 64, 128],stddev=0.01)),
'wc3': tf.Variable(tf.random_normal([3, 3, 128, 256],stddev=0.01)),
'wd1': tf.Variable(tf.random_normal([4*4*256, 1024],stddev=0.01)),
'wd2': tf.Variable(tf.random_normal([1024, 1024],stddev=0.01)),
'out': tf.Variable(tf.random_normal([1024, 2],stddev=0.01))
}
biases = {
'bc1': tf.Variable(tf.random_normal([64],stddev=0.01)),
'bc2': tf.Variable(tf.random_normal([128],stddev=0.01)),
'bc3': tf.Variable(tf.random_normal([256],stddev=0.01)),
'bd1': tf.Variable(tf.random_normal([1024],stddev=0.01)),
'bd2': tf.Variable(tf.random_normal([1024],stddev=0.01)),
'out': tf.Variable(tf.random_normal([n_classes]))
}
In [ ]:
# Construct model
pred = alex_net(x, weights, biases, keep_prob)
In [ ]:
# Define loss and optimizer
#cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(pred, y))
cost = tf.reduce_mean(tf.nn.weighted_cross_entropy_with_logits(pred, y,pos_weight=10))
optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(cost)
In [ ]:
# Evaluate model
correct_pred = tf.equal(tf.argmax(pred,1), tf.argmax(y,1))
accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))
In [ ]:
# Initializing the variables
init = tf.initialize_all_variables()
In [ ]:
X_train = X_train.reshape(X_train.shape[0],1024)
import matplotlib.pyplot as plt
%matplotlib inline
# Launch the graph
with tf.Session() as sess:
sess.run(init)
for epoch in range(training_epochs):
step = 1
# Keep training until reach max iterations
while step * batch_size < training_samples:
batch_xs, batch_ys = X_train[(batch_size*(step-1)):batch_size*(step)],y_train[(batch_size*(step-1)):batch_size*(step)]
# Fit training using batch data
sess.run(optimizer, feed_dict={x: batch_xs, y: batch_ys, keep_prob: dropout})
step += 1
# Calculate batch accuracy
if(epoch%1 == 0):
# Calculate batch loss
acc,conv1filter = sess.run([accuracy,weights['wc1']], feed_dict={x: batch_xs, y: batch_ys, keep_prob: 1.})
loss = sess.run(cost, feed_dict={x: batch_xs, y: batch_ys, keep_prob: 1.})
print "Epoch " + str(epoch) + ", Minibatch Loss= " + \
"{:.6f}".format(loss) + ", Training Accuracy= " + "{:.5f}".format(acc)
if(epoch%10 == 0):
plt.figure()
plt.matshow(make_mosaic(conv1filter.reshape(9,64).T, 8),cmap="gray")
#plt.matshow(conv1filter[:,:,0,1],cmap="gray")
plt.show()
#print "Optimization Finished!"
# Calculate accuracy for 256 mnist test images
print "Testing Accuracy:", sess.run(accuracy, feed_dict={x: X_test,
y: y_test,
keep_prob: 1.})
In [ ]: